package com.ffyc.cemp.web.interceptors;

import com.ffyc.cemp.common.exception.user.NoTokenException;
import com.ffyc.cemp.common.exception.user.PermissionDeniedException;
import com.ffyc.cemp.common.exception.user.TokenNotFoundException;
import com.ffyc.cemp.domain.entity.User;
import com.ffyc.cemp.tools.JwtUtils;
import com.ffyc.cemp.web.annotation.Permit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Component //放入springIoC工厂
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("进入拦截器......");


        //1.如果请求没有token，异常
        String token = request.getHeader("myToken");
        if (token == null || token.isEmpty()) throw new NoTokenException("前端未携带token异常, 访问失败");

        //2.检查redis中是否有此token
        User user = (User) redisTemplate.opsForValue().get(token);
        if (user == null) throw new TokenNotFoundException("token不存在异常，访问失败");

        String sign = user.getSign();

        Map<String, Object> map = JwtUtils.getInstance().verify(sign, token);//token过期验证

        //鉴权业务

        HandlerMethod method = (HandlerMethod) handler;
        Permit permit = method.getMethodAnnotation(Permit.class);
        if (permit != null) { //存在注解

            String methodRole = permit.role(); //注解中返回的role值
            String roleVal = String.valueOf(map.get("role"));


            if (!methodRole.equals(roleVal)) {
                throw new PermissionDeniedException("用户权限不足，拒绝访问");
            }


        }
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}
